#pragma once
#include "lib\TCollection.h"
#include "model\BaseModel.h"
#include "lib\Validator.h"
#include <set>
#include <vector>
#include <string>
#include <set>
#include <utility>
#include <iterator>

class Team : public BaseModel {
public:
  typedef TCollection<int>::IterBoolPair IterBoolPair;
  // constructors and destructor
  Team() {}
  
  explicit Team(std::string name) {
    name_ = name;
  }

  Team(std::string name, std::string address) {
    name_ = name;
    address_ = address;
  }
  
  virtual ~Team() {}


  // mutators
  void set_name(std::string name) {
    name_ = name;
  }

  void set_address(std::string address) {
    address_ = address;
  }

  // accessors
  std::string name() const {
    return name_;
  }

  std::string address() const {
    return address_;
  }

  int numplayers() {
    return num_players_;
  }

  // comparison operators
  bool operator==(const Team& team) const {
    return name_ == team.name();
  }

  bool operator<(const Team& team) const {
    return name_ < team.name();
  }

///
/// Performs validation on the model
///
bool Validate() {
  Validator v(this);
  v.Inject(name_, "Name").Length(3, 50).Chars(NameChars()).Required();
  v.Inject(address_, "Address").Length(3, 50).Chars(AddrChars());
  return errors().empty();
}


  TCollection<int>::IterBoolPair AddPlayer(int id) {
    return players_.Add(id);
  }

 TCollection<int>::CollectionPair GetPlayers() const {
   return players_.GetCollection();
  }

  int RemovePlayer(int id) {
    return players_.Delete(id);
  }

  int NumPlayers() const {
    return players_.Count();
  }

  void ClearPlayers() {
    players_.Clear();
  }

private:
///
/// Returns a string conntaining valid characters for the name_ attribute
///
std::string NameChars() {
  return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-\x91\x92\x9B\x9D\x86\x8F ";
}

///
/// Returns a string containing valid characters for the address_ attribute
///
std::string AddrChars() {
  return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890\x91\x92\x9B\x9D\x86\x8F ";
}

friend std::istream& operator>>(std::istream& is, Team& team);  
friend std::ostream& operator<<(std::ostream& os, const Team& team); 

  std::string name_;
  std::string address_;
  int num_players_;
  TCollection<int> players_;
};